home *** CD-ROM | disk | FTP | other *** search
- unit Drwsutl6;
-
- interface
- uses
- SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
- Forms, Dialogs, StdCtrls, Buttons, ExtCtrls, ShellAPI, FileCtrl;
-
- function CreateBitmapThumbNailFromBitmap( SourceBMP: TBitmap;
- TargetWidth ,
- TargetHeight : Integer ) : TBitmap;
-
- implementation
-
- function CreateBitmapThumbNailFromBitmap( SourceBMP: TBitmap;
- TargetWidth ,
- TargetHeight : Integer ) : TBitmap;
- var OutputBMP : TBitmap;
- HoldingBMP : TBitmap;
- TotalSourceColsPerOutputCol,
- TotalSourceRowsPerOutputRow,
- Counter_1 ,
- Counter_2 ,
- Counter_3 : Integer;
- CurrentColor : Longint;
- CurrentRowPointer,
- CurrentColPointer,
- BestLineSoFar ,
- TotalColorsInWork : Integer;
- MaxColorsSoFar : Integer;
- begin
- { if source smaller than or equal to thumbnail, stretchdraw and leave }
- if (( SourceBMP.Width <= TargetWidth ) and
- ( SourceBMP.Height <= TargetHeight )) then
- begin
- OutputBMP := TBitmap.Create;
- OutputBMP.Height := TargetHeight;
- OutputBMP.Width := TargetWidth;
- OutputBMP.Canvas.StretchDraw( Rect( 0 , 0 , TargetWidth , TargetHeight ) ,
- SourceBMP );
- CreateBitmapThumbNailFromBitmap := OutputBMP;
- exit;
- end;
- { Otherwise do thumbnail algorithm }
- { Create the interim holding bitmap; it will hold full width but resized # rows }
- HoldingBMP := TBitmap.Create;
- HoldingBMP.Width := SourceBMP.Width;
- HoldingBMP.Height := TargetHeight;
- { Create the final output bitmap; it will hold the resized values in both h & w }
- OutputBMP := TBitmap.Create;
- OutputBMP.Width := TargetWidth;
- OutputBMP.Height := TargetHeight;
- { Determine the total source rows and cols per output row and col }
- TotalSourceRowsPerOutputRow := ( SourceBMP.Height div TargetHeight );
- if ( SourceBMP.Height mod TargetHeight ) <> 0 then
- Inc( TotalSourceRowsPerOutputRow );
- TotalSourceColsPerOutputCol := ( SourceBMP.Width div TargetWidth );
- if ( SourceBMP.Width mod TargetWidth ) <> 0 then
- Inc( TotalSourceColsPerOutputCol );
- { Start resizing by setting initial row pointer }
- CurrentRowPointer := 0;
- { Loop through desired number of output rows }
- { Result will add row per group with highest color density to dest }
- for Counter_1 := 1 to TargetHeight do
- begin
- { Reset colors per line, best cols per line, and best line pointers }
- { Check all the lines in a group against each other }
- TotalColorsInWork := 0;
- MaxColorsSoFar := 0;
- BestLineSoFar := 0;
- for Counter_2 := 1 to TotalSourceRowsPerOutputRow do
- begin
- { Keep moving down the image }
- Inc( CurrentRowPointer );
- if CurrentRowPointer > SourceBMP.Height then break;
- { Start with no color }
- CurrentColor := -1;
- TotalColorsInWork := 0;
- { Actually scan the pixels }
- for Counter_3 := 1 to SourceBMP.Width do
- begin
- { if the current pixel value is different than the stored one }
- If SourceBMP.Canvas.Pixels[ Counter_3 - 1 , CurrentRowPointer - 1 ] <>
- CurrentColor then
- begin
- { Make the new color the stored one }
- CurrentColor := SourceBMP.Canvas.Pixels[ Counter_3 - 1 ,
- CurrentRowPointer - 1 ];
- { Increment total colors in the line }
- Inc( TotalColorsInWork );
- end;
- end;
- { At the end of the line, if there are more colors in the }
- { current line than the previous best line, then }
- if TotalColorsInWork > MaxColorsSoFar then
- begin
- { Set the new max to the current value }
- MaxColorsSoFar := TotalColorsInWork;
- { Set the new best line to the current pointer }
- BestLineSoFar := CurrentRowPointer;
- end;
- { Reset the total colors being checked }
- TotalColorsInWork := 0;
- end;
- MaxColorsSoFar := 0;
- { Once best line is determined, copy all its pixels to the holding bmp }
- for Counter_3 := 1 to SourceBMP.Width do
- begin
- HoldingBMP.Canvas.Pixels[ Counter_3 - 1 , Counter_1 - 1 ] :=
- SourceBMP.Canvas.Pixels[ Counter_3 - 1 , BestLineSoFar - 1 ];
- end;
- end;
- { Then resize by setting initial col pointer }
- CurrentColPointer := 0;
- { Loop through desired number of output cols }
- { Result will add col per group with highest color density to dest }
- for Counter_1 := 1 to TargetWidth do
- begin
- { Reset colors per line, best cols per line, and best line pointers }
- TotalColorsInWork := 0;
- MaxColorsSoFar := 0;
- BestLineSoFar := 0;
- { Check all the lines in a group against each other }
- for Counter_2 := 1 to TotalSourceColsPerOutputCol do
- begin
- { Keep moving down the image }
- Inc( CurrentColPointer );
- if CurrentColPointer > HoldingBMP.Width then break;
- { Start with no color }
- CurrentColor := -1;
- { Actually scan the pixels }
- for Counter_3 := 1 to HoldingBMP.Height do
- begin
- { if the current pixel value is different than the stored one }
- If HoldingBMP.Canvas.Pixels[ CurrentColPointer - 1 , Counter_3 - 1 ] <>
- CurrentColor then
- begin
- { Make the new color the stored one }
- CurrentColor := HoldingBMP.Canvas.Pixels[ CurrentColPointer - 1 ,
- Counter_3 - 1 ];
- { Increment total colors in the line }
- Inc( TotalColorsInWork );
- end;
- end;
- { At the end of the line, if there are more colors in the }
- { current line than the previous best line, then }
- if TotalColorsInWork > MaxColorsSoFar then
- begin
- { Set the new max to the current value }
- MaxColorsSoFar := TotalColorsInWork;
- { Set the new best line to the current pointer }
- BestLineSoFar := CurrentColPointer;
- end;
- { Reset the total colors being checked }
- TotalColorsInWork := 0;
- end;
- { Once best line is determined, copy all its pixels to the holding bmp }
- for Counter_3 := 1 to HoldingBMP.Height do
- begin
- OutputBMP.Canvas.Pixels[ Counter_1 - 1 , Counter_3 - 1 ] :=
- HoldingBMP.Canvas.Pixels[ BestLineSoFar - 1 , Counter_3 - 1 ];
- end;
- end;
- { Finally, output the thumbnail image }
- CreateBitmapThumbNailFromBitmap := OutputBMP;
- { And free the working copy }
- HoldingBMP.Free;
- end;
-
- end.
-